/**
 * 用户相关业务逻辑
 */
const { querySql, startTransaction, commitTransaction, rollbackTransaction } = require('../utils/index');
const md5 = require('../utils/md5');
const jwt = require('jsonwebtoken');
const boom = require('boom');
const { validationResult } = require('express-validator');
const {
  CODE_ERROR,
  CODE_SUCCESS,
  PRIVATE_KEY,
  JWT_EXPIRED
} = require('../utils/constant');
/* 提取公共的验证逻辑 */
function validateRequest(req, next) {
  const err = validationResult(req);
  if (!err.isEmpty()) {
    const [{ msg }] = err.errors;
    next(boom.badRequest(msg));
    return false;
  }
  return true;
}
/* 提取响应逻辑 */
function sendResponse(res, code, msg, data = null) {
  res.json({ code, msg, data });
}
/* 生成 Token */
function generateToken(username) {
  return jwt.sign({ username }, PRIVATE_KEY, { expiresIn: JWT_EXPIRED });
}
/* 提取用户查询逻辑 */
async function findUserByUsername(username) {
  const query = `select * from users where username = ?`;
  return await querySql(query, [username]);
}
/* 提取用户查询逻辑 - 新增邮箱查询 */
async function findUserByEmail(email) {
  const query = `select * from users where email = ?`;
  return await querySql(query, [email]);
}
async function executeTransaction(task) {
  const conn = await startTransaction();
  try {
    const result = await task(conn);
    await commitTransaction(conn);
    return result;
  } catch (error) {
    await rollbackTransaction(conn);
    throw error;
  }
}
/* 验证用户密码 */
async function validateUserPassword(username, password) {
  const query = `select * from users where username = ? and password = ?`;
  return await querySql(query, [username, md5(password)]);
}
/* 登录 */
async function login(req, res, next) {
  if (!validateRequest(req, next)) return;
  try {
    const { username, password } = req.body;
    const user = await validateUserPassword(username, password);
    if (user.length===0) {
      return sendResponse(res, CODE_ERROR, '用户名或密码错误');
    }
    if (user[0].status !== 'active') {
      return sendResponse(res, CODE_ERROR, '您的账号已被禁用，请联系管理员');
    }
    const token = generateToken(username);
    sendResponse(res, CODE_SUCCESS, '登录成功', { user, token });
  } catch (error) {
    next(boom.badImplementation(error.message));
  }
}
/* 注册 */
async function register(req, res, next) {
  if (!validateRequest(req, next)) return;
  try {
    const {
      username,
      password,
      email,
      role = 'user', // 默认角色为 user
      bio = '', // 默认 bio 为空
      avatar_url = '', // 默认头像 URL 为空
    } = req.body;

    // 检查用户名是否已存在
    const existingUser = await findUserByUsername(username);
    if (existingUser.length > 0) {
      return sendResponse(res, CODE_ERROR, '用户名已存在');
    }

    // 检查邮箱是否已注册
    const existingEmail = await findUserByEmail(email);
    if (existingEmail.length > 0) {
      return sendResponse(res, CODE_ERROR, '邮箱已被注册');
    }
    // 插入新用户
    const insertQuery = `
      INSERT INTO users(username, password, email, role, bio, avatar_url)
      VALUES(?, ?, ?, ?, ?, ?)
    `;
    const result = await querySql(insertQuery, [
      username,
      md5(password),
      email,
      role,
      bio,
      avatar_url,
    ]);

    if (!result || result.affectedRows === 0) {
      return sendResponse(res, CODE_ERROR, '注册失败');
    }
    const token = generateToken(username);
    sendResponse(res, CODE_SUCCESS, '注册成功');
  } catch (error) {
    next(boom.badImplementation(error.message));
  }
}
/* 重置密码 */
async function resetPwdByEmail(req, res, next) {
  try {
    const { email, password } = req.body;
    // 验证新密码是否为空
    if (!password) {
      return sendResponse(res, CODE_ERROR, '新密码不能为空');
    }
    // 验证邮箱是否已注册
    const existingEmail = await findUserByEmail(email);
    if (existingEmail.length <= 0) {
      return sendResponse(res, CODE_ERROR, '邮箱未注册');
    }
    // 更新密码
    const updateQuery = `update users set password = ? where email = ?`;
    const result = await querySql(updateQuery, [md5(password), email]);
    if (!result || result.length === 0) {
      return sendResponse(res, CODE_ERROR, '重置密码失败');
    }
    sendResponse(res, CODE_SUCCESS, '重置密码成功');
  } catch (error) {
    next(boom.badImplementation(error.message));
  }
}
// 图片上传 -- 用户部分
async function handleAvatarUpload(req, res) {
  try {
    if (!req.file) {
      return res.status(400).json({
        code: 400,
        message: '请选择有效的图片文件',
        data: null
      });
    }
    // 生成完整URL
    const avatarUrl = `${req.protocol}://${req.get('host')}/public/avatars/${req.file.filename}`;
    
    return res.json({
      code: 200,
      message: '上传成功',
      data: {
        url: avatarUrl
      }
    });
  } catch (error) {
    console.error('上传错误:', error);
    return res.status(500).json({
      code: 500,
      message: '服务器处理文件时出错',
      data: null
    });
  }
}
// 优化后的用户信息更新方法
async function updateUserProfile(req, res, next) {
  try {
    const userId = req.body.id;
    const updates = req.body;
    // 定义允许更新的字段白名单
    const validFields = ['username', 'email', 'password', 'bio','role','avatar_url'];
    // 使用事务包装器执行核心逻辑
    const { oldAvatar } = await executeTransaction(async (conn) => {
      // 获取当前头像（带行锁）
      const [user] = await querySql(
        'SELECT avatar_url AS oldAvatar FROM users WHERE id = ? FOR UPDATE', 
        [userId], 
        conn
      );
      // 过滤非法字段并构建更新数据
      const updateData = {};
      for (const key of Object.keys(updates)) {
        if (validFields.includes(key) && updates[key] !== undefined) {
          updateData[key] = updates[key];
        }
      }
      // 执行有条件更新
      if (Object.keys(updateData).length > 0) {
        await querySql(
          'UPDATE users SET ? WHERE id = ?',
          [updateData, userId],
          conn
        );
      }
      return { oldAvatar: user.oldAvatar };
    });
    // 获取更新后的数据
    const [user] = await querySql(
      'SELECT * FROM users WHERE id = ?',
      [userId]
    );
    sendResponse(res, CODE_SUCCESS, '更新成功', { 
      ...user,
    });
  } catch (error) {
    next(boom.badImplementation(error.message));
  }
}
// 获取所有用户
async function getAllUsers(req, res, next) {
  try {
    // 从请求中获取分页参数，默认 page=1, limit=10
    const { currentPage = 1, pageSize = 10, sortBy = 'created_at', sortOrder = 'DESC' } = req.body;
    const offset = (currentPage - 1) * pageSize;

    // 验证排序字段和顺序
    const validSortFields = ['created_at', 'updated_at', 'username']; // 允许排序的字段
    const validSortOrders = ['ASC', 'DESC']; // 允许的排序顺序

    if (!validSortFields.includes(sortBy) || !validSortOrders.includes(sortOrder)) {
      throw new Error('无效的排序参数');
    }

    // 查询用户列表（分页 + 排序）
    const users = await querySql(
      `SELECT * 
       FROM users 
       ORDER BY ${sortBy} ${sortOrder} 
       LIMIT ? OFFSET ?`,
      [parseInt(pageSize), parseInt(offset)]
    );
    // 查询总用户数
    const [total] = await querySql('SELECT COUNT(*) AS total FROM users');
    // 返回分页数据
    sendResponse(res, CODE_SUCCESS, '获取用户列表成功', {
      users,
      total: total.total,
      currentPage: parseInt(currentPage),
      pageSize: parseInt(pageSize),
    });
  } catch (error) {
    // 错误处理
    next(boom.badImplementation(error.message || '获取用户列表失败，请稍后重试'));
  }
}
/**
 * 冻结/解冻用户
 */
async function freezeUser(req, res, next) {
  try {
    const { userId, status } = req.body;
    if (!userId || !['active', 'frozen'].includes(status)) {
      return sendResponse(res, CODE_ERROR, '参数错误');
    }

    const updateQuery = `UPDATE users SET status = ? WHERE id = ?`;
    const result = await querySql(updateQuery, [status, userId]);

    if (!result || result.affectedRows === 0) {
      return sendResponse(res, CODE_ERROR, '操作失败');
    }

    sendResponse(res, CODE_SUCCESS, '操作成功');
  } catch (error) {
    next(boom.badImplementation(error.message));
  }
}
async function deleteUser(req, res, next) {
  try {
    const { userId } = req.body;
    if (!userId) {
      return sendResponse(res, CODE_ERROR, '参数错误');
    }

    const deleteQuery = `DELETE FROM users WHERE id = ?`;
    const result = await querySql(deleteQuery, [userId]);

    if (!result || result.affectedRows === 0) {
      return sendResponse(res, CODE_ERROR, '删除失败');
    }

    sendResponse(res, CODE_SUCCESS, '删除成功');
  } catch (error) {
    next(boom.badImplementation(error.message));
  }
}
module.exports = {
  login,
  register,
  resetPwdByEmail,
  handleAvatarUpload,
  updateUserProfile,
  getAllUsers,
  freezeUser,
  deleteUser
};